#pragma once

#include "vio/front_end/frame.h"
#include "vio/front_end/point.h"
#include "vio/vio_common.h"

namespace vio {
class Frame;
class Point;
// a salient image region that is tracked across frames
struct Feature {
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
  typedef std::shared_ptr<Feature> Ptr;
  enum FeatureType { CORNER, EDGELET };

  FeatureType type;  // type can be corner or edgelet
  std::weak_ptr<Frame>
      frame_ptr;       // pointer to frame in which the feature was detected
  Eigen::Vector2d px;  // coordinates in pixels on pyramid level 0
  Eigen::Vector3d
      bearing;  // unit-bearing vector of the feature (unit depth camera frame)
  int level;    // image pyramid level where feature was extracted
  std::weak_ptr<Point>
      point_ptr;         // pointer to 3D point which corresponds to the feature
  Eigen::Vector2d grad;  // dominant gradient direction for edglets, normalized

  Feature(std::shared_ptr<Frame> frame,
          const Eigen::Vector2d& px,
          const int& l);

  Feature(std::shared_ptr<Frame> frame,
          const Eigen::Vector2d& px,
          const Eigen::Vector3d& b,
          const int& l);

  Feature(std::shared_ptr<Frame> frame,
          Point::Ptr point,
          const Eigen::Vector2d& px,
          const Eigen::Vector3d& b,
          const int& l);
};
}  // namespace vio
